﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace INSTA.BankSystem.BLL
{
    /// <summary>
    /// Base class for all  <see cref="Bank"/> accounts.
    /// </summary>
    public abstract class AccountBase
    {
        public event EventHandler<OverdrawnEventArgs> OnExcessOverdrawnWithdrawal;

        // Backers variables for the properties.
        private Customer _holder;
        private double _balance;


        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="customer">The customer.</param>
        /// <param name="initialDeposit">The initial deposit.</param>
        public AccountBase(Customer customer, double initialDeposit)
        {
            _holder = customer;

            Deposit(initialDeposit);


        }

        /**********************************************************************
         * 
         * Methods
         *
         **********************************************************************/ 



        /// <summary>
        /// Deposits the specified deposit.
        /// </summary>
        /// <param name="deposit">The deposit.</param>
        public void Deposit(double deposit)
        {
            if (deposit >= 0)
            {
                _balance += deposit;
            }
        }


        /// <summary>
        /// Withdraws the specified deposit.
        /// </summary>
        /// <param name="deposit">The deposit.</param>
        public void Withdraw(double deposit)
        {
            if (deposit >= 0)
            {
                _balance -= deposit;

                if (IsAccountExcessOverdrawn)
                {
                    Fire_OnExcessOverdrawnWithdrawal();
                }
            }
        }

        /// <summary>
        /// Fires the OnExcessOverdrawnWithdrawal event.
        /// </summary>
        protected virtual void Fire_OnExcessOverdrawnWithdrawal()
        {
            if (OnExcessOverdrawnWithdrawal != null)
            {
                var args = new OverdrawnEventArgs(Balance - GetAuthorizedOverdrawn(),
                                                  Balance);
                OnExcessOverdrawnWithdrawal(this, args);
            }
        }


        /// <summary>
        /// Withdraws the monthly fees.
        /// </summary>
        public abstract void WithdrawMonthlyFees();

        /// <summary>
        /// Gets the maximum authorized overdrawn (découvert) amount.
        /// </summary>
        /// <returns>the maximum authorized overdrawn (découvert) amount.</returns>
        public abstract double GetAuthorizedOverdrawn();



        /**********************************************************************
         * 
         * Properties
         *
         **********************************************************************/ 

        public bool IsAccountExcessOverdrawn
        {
            get { return Balance < -GetAuthorizedOverdrawn(); }
        }


        public Customer Holder
        {
            get { return _holder; }
            //protected set { _holder = value; }
        }

        public double Balance
        {
            get { return _balance; }
            //private set { _balance = value; }
        }



    }
}
